/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package eu.webhib.test.utils;

import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.log4j.Logger;

public class Utils {
   //
   private static final Logger log = Logger.getLogger(Utils.class);
   //
   public static boolean deleteDirectory(File path) {
      if (path.exists()) {
         File[] files = path.listFiles();
         for (int i = 0; i < files.length; i++) {
            if (files[i].isDirectory()) {
               deleteDirectory(files[i]);
            } else {
               files[i].delete();
            }
         }
      }
      return (path.delete());
   }
   //
   /* see http://snippets.dzone.com/posts/show/4831 */
   /**
    * Scans all classes accessible from the context class loader which belong to the given package and subpackages.
    *
    * @param packageName The base package
    * @return The classes
    * @throws ClassNotFoundException
    * @throws IOException
    */
   @SuppressWarnings("unchecked")
   public static Class[] getClasses(String packageName) throws ClassNotFoundException, IOException {
      ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
      assert classLoader != null;
      String path = packageName.replace('.', '/');
      Enumeration<URL> resources = classLoader.getResources(path);
      List<File> dirs = new ArrayList<File>();
      while (resources.hasMoreElements()) {
         URL resource = resources.nextElement();
         String fileName = resource.getFile();
         String fileNameDecoded = URLDecoder.decode(fileName, "UTF-8");
         dirs.add(new File(fileNameDecoded));
      }
      ArrayList<Class> classes = new ArrayList<Class>();
      for (File directory : dirs) {
         classes.addAll(findClasses(directory, packageName));
      }
      return classes.toArray(new Class[classes.size()]);
   }

   /**
    * Recursive method used to find all classes in a given directory and subdirs.
    *
    * @param directory   The base directory
    * @param packageName The package name for classes found inside the base directory
    * @return The classes
    * @throws ClassNotFoundException
    */
   @SuppressWarnings("unchecked")
   private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
      List<Class> classes = new ArrayList<Class>();
      if (!directory.exists()) {
         return classes;
      }
      File[] files = directory.listFiles();
      for (File file : files) {
         String fileName = file.getName();
         if (file.isDirectory()) {
            assert !fileName.contains(".");
            classes.addAll(findClasses(file, packageName + "." + fileName));
         } else if (fileName.endsWith(".class") && !fileName.contains("$")) {
            Class _class;
            try {
               _class = Class.forName(packageName + '.' + fileName.substring(0, fileName.length() - 6));
            } catch (ExceptionInInitializerError e) {
               // happen, for example, in classes, which depend on
               // Spring to inject some beans, and which fail,
               // if dependency is not fulfilled
               _class = Class.forName(packageName + '.' + fileName.substring(0, fileName.length() - 6),
                       false, Thread.currentThread().getContextClassLoader());
            }
            classes.add(_class);
         }
      }
      return classes;
   }

}
